package com.hnyc.token;

import com.hnyc.domain.OnlineTokenInfo;
import com.hnyc.service.IOnlineTokenInfoService;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @auther zero
 * @date 2023/3/13
 **/
@Component
public class TokenCache {
    Map<String, OnlineTokenInfo> tokenHolder=new HashMap<>();
    @Resource
    IOnlineTokenInfoService tokenInfoService;
    @Resource
    RedisCache redisCache;
    @PostConstruct
    public void initHolderFromDb(){
        List<OnlineTokenInfo> list = tokenInfoService.selectOnlineTokenInfoList(new OnlineTokenInfo());
        list.stream().forEach(t->{
           // 缓存
            cacheToken(t);
        });
    }
    public String getShopAccessToken(long shopId){
        OnlineTokenInfo onlineTokenInfo = tokenHolder.get(TokenKeyHelper.shopAccessTokenKey(shopId));
        if(onlineTokenInfo==null|| StringUtils.isEmpty(onlineTokenInfo.getAccessToken())){
            onlineTokenInfo=redisCache.getCacheObject(TokenKeyHelper.shopAccessTokenKey(shopId));
        }
        if(onlineTokenInfo!=null|| StringUtils.isNotEmpty(onlineTokenInfo.getAccessToken())){
            return onlineTokenInfo.getAccessToken();
        }
        throw new RuntimeException("token 不存在");
    }
    public OnlineTokenInfo getMerchantRefreshToken(String pltName,Long id) {

        OnlineTokenInfo token = tokenHolder.get(TokenKeyHelper.merchantRefreshKey(id));
        if (token != null) {
            return token;
        }
        token = redisCache.getCacheObject(TokenKeyHelper.merchantRefreshKey(id));
        if (token != null) {
            return token;
        }
        OnlineTokenInfo query = new OnlineTokenInfo();
        query.setPltName(pltName);
//        query.setAccountId(id);
        query.setMerchantId(id);
        List<OnlineTokenInfo> tokenList = tokenInfoService.selectOnlineTokenInfoList(query);
        if (tokenList.size() > 0) {
            return tokenList.get(0);
        }
        throw new RuntimeException("读取token失败 merchant：" + id);
    }

        public OnlineTokenInfo getAccountRefreshToken(String pltName,Long id){

        OnlineTokenInfo token = tokenHolder.get(TokenKeyHelper.accountRefreshKey(id));
        if(token!=null){
            return token;
        }
        token=redisCache.getCacheObject(TokenKeyHelper.accountRefreshKey(id));
        if(token!=null){
            return token;
        }
        OnlineTokenInfo query = new OnlineTokenInfo();
        query.setPltName(pltName);
        query.setAccountId(id);
        List<OnlineTokenInfo> tokenList = tokenInfoService.selectOnlineTokenInfoList(query);
        if(tokenList.size()>0){
            return tokenList.get(0);
        }
        throw new RuntimeException("读取token失败 accountId："+id);
    }
    public OnlineTokenInfo getShopRefreshToken(String pltName,Long id){

        OnlineTokenInfo token = tokenHolder.get(TokenKeyHelper.shopRefreshTokenKey(id));
        if(token!=null){
            return token;
        }
        token=redisCache.getCacheObject(TokenKeyHelper.shopRefreshTokenKey(id));
        if(token!=null){
            return token;
        }
        OnlineTokenInfo query = new OnlineTokenInfo();
        query.setPltName(pltName);
        query.setShopId(id);
        List<OnlineTokenInfo> tokenList = tokenInfoService.selectOnlineTokenInfoList(query);
        if(tokenList.size()>0){
            return tokenList.get(0);
        }
        throw new RuntimeException("读取token失败 accountId："+id);
    }
    public void cacheToken(OnlineTokenInfo t){
        if(t.getMerchantId()!=null){
           cacheMerchantToken(t);
        }
        if(t.getShopId()!=null){
           cacheShopToken(t);
        }
    }
    public void cacheAccountToken(OnlineTokenInfo token){
        // todo 判断access token 是否过期
        tokenHolder.put(TokenKeyHelper.accountAccessKey(token.getAccountId()),token);
        // todo 判断refresh token 是否过期
        tokenHolder.put(TokenKeyHelper.accountRefreshKey(token.getAccountId()),token);
        // 缓存到redis
        // 缓存shop token
        redisCache.setCacheObject(
                TokenKeyHelper.accountAccessKey(token.getAccountId()),
                token.getAccessToken(),
                (int)(token.getExpireIn()-5),// 需要刨除获取的耗时
                TimeUnit.SECONDS);
        // 缓存refresh token
        redisCache.setCacheObject(
                TokenKeyHelper.accountRefreshKey(token.getAccountId()),
                token.getRefreshToken(),
                (int)(token.getExpireIn()-2),// 需要刨除获取的耗时
                TimeUnit.DAYS);
    }
    public void cacheShopToken(OnlineTokenInfo token){
        // todo 判断access token 是否过期
        tokenHolder.put(TokenKeyHelper.shopAccessTokenKey(token.getShopId()),token);
        // todo 判断refresh token 是否过期
        tokenHolder.put(TokenKeyHelper.shopRefreshTokenKey(token.getShopId()),token);
        // 缓存shop token
        redisCache.setCacheObject(TokenKeyHelper.shopAccessTokenKey(token.getShopId()),
                token.getAccessToken(),
                (int)(token.getExpireIn()-5),// 需要刨除获取的耗时
                TimeUnit.SECONDS);
        // 缓存refresh token
        redisCache.setCacheObject(TokenKeyHelper.shopRefreshTokenKey(token.getShopId()),
                token.getRefreshToken(),
                (int)(token.getExpireIn()-2),// 需要刨除获取的耗时
                TimeUnit.DAYS);
    }
    public void cacheMerchantToken(OnlineTokenInfo token){
        // todo 判断access token 是否过期
        tokenHolder.put(TokenKeyHelper.merchantAccessKey(token.getShopId()),token);
        // todo 判断refresh token 是否过期
        tokenHolder.put(TokenKeyHelper.merchantRefreshKey(token.getShopId()),token);
        // 缓存shop token
        redisCache.setCacheObject(TokenKeyHelper.merchantAccessKey(token.getShopId()),
                token.getAccessToken(),
                (int)(token.getExpireIn()-5),// 需要刨除获取的耗时
                TimeUnit.SECONDS);
        // 缓存refresh token
        redisCache.setCacheObject(TokenKeyHelper.merchantRefreshKey(token.getShopId()),
                token.getRefreshToken(),
                (int)(token.getExpireIn()-2),// 需要刨除获取的耗时
                TimeUnit.DAYS);
    }
}
